0.1 Load all of the throw data

# load omnibus dataframe
omnibus_df <- read_delim("../data/processed/omnibus/omnibus_raw.csv",
  delim = ",",
  col_types = cols(
    .default = col_double(),
    type = col_factor(),
    ppid = col_factor(),
    exp_label = col_factor(),
    experiment = col_factor(),
    hand = col_factor(),
    camera_tilt = col_factor(),
    surface_tilt = col_factor(),
    target = col_factor(),
    test_type = col_factor(),
    prior_anim = col_factor(),
    baseline_block = col_factor(),
    task_type = col_factor(),
    surface = col_factor(),
    anim_type = col_factor()
  )
) %>%
  filter(block_num > 4) # filter out practice blocks

1 Visualizing data (univariate)

Vectors representing the throw velocity (trace 0) and the velocity applied to the ball (trace 1). The y dimention of the throw is essentially ignored (in reality there is a slight tilt added to account for the tilt of the surface).

test_ppt <- 3

test_df <- omnibus_df %>% filter(ppid == test_ppt)


trial <- 250
trial_df <- filter(test_df, trial_num == trial)

x <- trial_df$flick_velocity_x 
y <- trial_df$flick_velocity_y
z <- trial_df$flick_velocity_z

x2 <- trial_df$flick_direction_x * -1
y2 <- trial_df$flick_direction_y * -1
z2 <- trial_df$flick_direction_z * -1

# plot both
p <- plot_ly(x = c(0, x), y = c(0, y), z = c(0, z), type = "scatter3d", mode = "lines") %>%
  add_trace(x = c(0, x2), y = c(0, y2), z = c(0, z2), type = "scatter3d", mode = "lines") %>%
  layout(scene = list(
    xaxis = list(title = "x", range = c(-2, 2)),
    yaxis = list(title = "y", range = c(-1, 3)),
    zaxis = list(title = "z", range = c(-1, 3))
  ))

# Render the plot
p

note: this is a rotated trial

1.0.1 Distribution of errors

# plot distribution of error_size
p <- ggplot(omnibus_df, aes(x = error_size,
                            fill = type)) +
  geom_histogram(binwidth = .5, alpha = .6) +
  theme_minimal() +
  theme(text = element_text(size = 11)) +
  scale_fill_manual(values=c("#f9982c", "#d40000")) +
  labs(x = "Error Size (cm)", y = "Count")

p

1.0.2 Distribution of throw angles

# plot distribution of error_size
p <- ggplot(omnibus_df, aes(x = throw_deviation,
                            fill = type)) +
  geom_histogram(binwidth = 1, alpha = .6) +
  theme_minimal() +
  theme(text = element_text(size = 11)) +
  scale_fill_manual(values=c("#f9982c", "#d40000")) +
  labs(
    x = "Throw Angle (°)", y = "Count"
  ) +  # dashed lines at 0, -15, -30
  geom_vline(
    xintercept = c(0, -15, -30), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) + # ticks of 15 degrees
  scale_x_continuous(
    breaks = c(-30, 0, 30, -60, -90)
  )

p

2 Original Experiments

2.0.1 Plot ANGULAR DEVIATIONS (hand angles)

Note: Blues = Acceleration Perturbations

# rest of the exps
data_per_group <- omnibus_df %>%
  filter(exp_label == "original_exps" | exp_label == "curved_path") %>%
  group_by(experiment, test_type, trial_num) %>%
  summarise(
    mean_deviation = mean(throw_deviation),
    ci_deviation = vector_confint(throw_deviation),
    .groups = "drop"
  )

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = trial_num, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number",
    y = "Throw Angle (°)"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, -30), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(-15), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# p <- p +
#   scale_y_continuous(
#     limits = c(-10, 35),
#     breaks = c(0, 15, 30),
#     labels = c(0, 15, 30)
#   ) +
#   scale_x_continuous(
#     limits = c(0, 180),
#     breaks = c(0, 60, 120, 180),
#     labels = c(0, 60, 120, 180)
#   )

# set font size to 11
p <- p +
  theme(text = element_text(size = 11))

# add confidence intervals and data points
p <- p + geom_ribbon(
  aes(
    ymin = mean_deviation - ci_deviation,
    ymax = mean_deviation + ci_deviation,
    fill = experiment
  ),
  colour = NA, alpha = 0.3
) + geom_line()

# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)


# # save
# if (save_plots) {
#   ggsave(
#   p,
#   filename = "../plots/paper_figs/sr_30_training.pdf", device = "pdf",
#   height = 4, width = 6
#   )
#   }

ggplotly(p)

# p

2.0.2 Trial sets of interest only

Note: Blues = Acceleration Perturbations

# filter out just the trials of interest
data_per_group <- data_per_group %>%
  filter(
    test_type != "other"
  )
# add a dummy column with repeating sequence
# NOTE: this can't be combined with above since we are using nrow
data_per_group <- data_per_group %>%
  mutate(dummy_x = rep(1:(nrow(data_per_group) / NUM_EXPS),
    length.out = nrow(data_per_group)
  ))

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = dummy_x, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number",
    y = "Throw Angle (°)"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, -30), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(-15), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# add confidence intervals and data points
for (unique_test_type in unique(data_per_group$test_type)) {
  # get the data for this block
  to_plot_data <- filter(data_per_group, test_type == unique_test_type)

  p <- p + geom_ribbon(
    data = to_plot_data,
    aes(
      ymin = mean_deviation - ci_deviation,
      ymax = mean_deviation + ci_deviation,
      fill = experiment
    ), colour = NA, alpha = 0.3
  ) + geom_line(
    data = to_plot_data
  )
}

# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)

ggplotly(p)

2.0.3 Plot NORMALIZED ANGULAR DEVIATIONS (hand angles)

Note: Blues = Acceleration Perturbations

# rest of the exps
data_per_group <- omnibus_df %>%
  filter(exp_label == "original_exps" | exp_label == "curved_path") %>%
  group_by(experiment, test_type, trial_num) %>%
  summarise(
    mean_deviation = mean(norm_throw_deviation),
    ci_deviation = vector_confint(norm_throw_deviation),
    .groups = "drop"
  )

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = trial_num, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number",
    y = "Normalized Throw Angle"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, 1, 2), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# p <- p +
#   scale_y_continuous(
#     limits = c(-10, 35),
#     breaks = c(0, 15, 30),
#     labels = c(0, 15, 30)
#   ) +
#   scale_x_continuous(
#     limits = c(0, 180),
#     breaks = c(0, 60, 120, 180),
#     labels = c(0, 60, 120, 180)
#   )

# set font size to 11
p <- p +
  theme(text = element_text(size = 11))

# add confidence intervals and data points
p <- p + geom_ribbon(
  aes(
    ymin = mean_deviation - ci_deviation,
    ymax = mean_deviation + ci_deviation,
    fill = experiment
  ),
  colour = NA, alpha = 0.3
) + geom_line()

# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)


# # save
# if (save_plots) {
#   ggsave(
#   p,
#   filename = "../plots/paper_figs/sr_30_training.pdf", device = "pdf",
#   height = 4, width = 6
#   )
#   }

ggplotly(p)

# p

2.0.4 Trial sets of interest only

Note: Blues = Acceleration Perturbations

# filter out just the trials of interest
data_per_group <- data_per_group %>%
  filter(
    test_type != "other"
  )
# add a dummy column with repeating sequence
# NOTE: this can't be combined with above since we are using nrow
data_per_group <- data_per_group %>%
  mutate(dummy_x = rep(1:(nrow(data_per_group) / NUM_EXPS),
    length.out = nrow(data_per_group)
  ))

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = dummy_x, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number",
    y = "Normalized Throw Angle"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, 1, 2), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# add confidence intervals and data points
for (unique_test_type in unique(data_per_group$test_type)) {
  # get the data for this block
  to_plot_data <- filter(data_per_group, test_type == unique_test_type)

  p <- p + geom_ribbon(
    data = to_plot_data,
    aes(
      ymin = mean_deviation - ci_deviation,
      ymax = mean_deviation + ci_deviation,
      fill = experiment
    ), colour = NA, alpha = 0.3
  ) + geom_line(
    data = to_plot_data
  )
}

# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)

ggplotly(p)

2.0.5 Plot ERROR SIZE

Note: Blues = Acceleration Perturbations

# original experiments only
data_per_group <- omnibus_df %>%
  filter(exp_label == "original_exps" | exp_label == "curved_path") %>%
  group_by(experiment, test_type, trial_num) %>%
  summarise(
    mean_deviation = mean(error_size),
    ci_deviation = vector_confint(error_size),
    .groups = "drop"
  )

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = trial_num, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number",
    y = "Absolute Target Error (cm)"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, 40), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(20), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# p <- p +
#   scale_y_continuous(
#     limits = c(-10, 35),
#     breaks = c(0, 15, 30),
#     labels = c(0, 15, 30)
#   ) +
#   scale_x_continuous(
#     limits = c(0, 180),
#     breaks = c(0, 60, 120, 180),
#     labels = c(0, 60, 120, 180)
#   )

# set font size to 11
p <- p +
  theme(text = element_text(size = 11))

# add confidence intervals and data points
p <- p + geom_ribbon(
  aes(
    ymin = mean_deviation - ci_deviation,
    ymax = mean_deviation + ci_deviation,
    fill = experiment
  ),
  colour = NA, alpha = 0.3
) + geom_line()

# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)


# # save
# if (save_plots) {
#   ggsave(
#   p,
#   filename = "../plots/paper_figs/sr_30_training.pdf", device = "pdf",
#   height = 4, width = 6
#   )
#   }

ggplotly(p)

# p

visible vs non-visible tilt doesn’t affect the 15-degree rotation condition. But affects all other conditions. So 15-degree rotation

2.0.6 Trial sets of interest only

Note: Blues = Acceleration Perturbations

# filter out just the trials of interest
data_per_group <- data_per_group %>%
  filter(
    test_type != "other"
  )
# add a dummy column with repeating sequence
# NOTE: this can't be combined with above since we are using nrow
data_per_group <- data_per_group %>%
  mutate(dummy_x = rep(1:(nrow(data_per_group) / NUM_EXPS),
    length.out = nrow(data_per_group)
  ))

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = dummy_x, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number",
    y = "Absolute Target Error (cm)"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, 40), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(20), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# add confidence intervals and data points
for (unique_test_type in unique(data_per_group$test_type)) {
  # get the data for this block
  to_plot_data <- filter(data_per_group, test_type == unique_test_type)

  p <- p + geom_ribbon(
    data = to_plot_data,
    aes(
      ymin = mean_deviation - ci_deviation,
      ymax = mean_deviation + ci_deviation,
      fill = experiment
    ), colour = NA, alpha = 0.3
  ) + geom_line(
    data = to_plot_data
  )
}

# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)

ggplotly(p)

3 Animated Surface Follow-up

3.0.1 Plot ANGULAR DEVIATIONS (hand angles)

# isolate animate_surface exp
data_per_group <- omnibus_df %>%
  filter(exp_label == "animate_surface") %>%
  group_by(prior_anim, block_num, trial_num_in_block, trial_num) %>%
  summarise(
    mean_deviation = mean(throw_deviation),
    ci_deviation = vector_confint(throw_deviation)
  )

# order the factors for assigning colour pallets
data_per_group$prior_anim <- factor(
  data_per_group$prior_anim,
  levels = c(
    "none", "half_anim", "full_anim"
  )
)

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = trial_num, y = mean_deviation,
      ymin = mean_deviation - ci_deviation,
      ymax = mean_deviation + ci_deviation
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number",
    y = "Throw Angle (°)"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, -30), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(-15), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# p <- p +
#   scale_y_continuous(
#     limits = c(-10, 35),
#     breaks = c(0, 15, 30),
#     labels = c(0, 15, 30)
#   ) +
#   scale_x_continuous(
#     limits = c(0, 180),
#     breaks = c(0, 60, 120, 180),
#     labels = c(0, 60, 120, 180)
#   )

# set font size to 11
p <- p +
  theme(text = element_text(size = 11))

# repeat for prior_anim == "half", "full" and "wait"
for (unique_prior_anim in unique(data_per_group$prior_anim)) {
  # get the data for this block
  to_plot_data <- filter(data_per_group, prior_anim == unique_prior_anim)
  # loop through the unique blocks in to_plot_data
  for (block in unique(to_plot_data$block_num)) {
    # get the data for this block
    block_data <- filter(to_plot_data, block_num == block)
    # add the data, use the pallete_list to get the colour
    p <- p + geom_ribbon(
      data = block_data,
      aes(fill = prior_anim),
      colour = NA, alpha = 0.3
    ) + geom_line(
      data = block_data,
      aes(colour = prior_anim)
    )
  }
}

# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)

# # save
# if (save_plots) {
#   ggsave(
#   p,
#   filename = "../plots/paper_figs/sr_30_training.pdf", device = "pdf",
#   height = 4, width = 6
#   )
#   }

ggplotly(p)
# p

3.0.2 Washout trials after half VS full animations

# first, isolate the data
data <- omnibus_df %>%
  filter(
    exp_label == "animate_surface",
    baseline_block == FALSE,
    test_type == "washout_anim"
  )

data_per_ppt <- data %>%
  group_by(ppid, prior_anim, trial_num_in_block) %>%
  summarise(
    ppt_mean_deviation = median(throw_deviation),
    ppt_ci_deviation = vector_confint(throw_deviation),
    n = n()
  )

data_per_group <- data_per_ppt %>%
  group_by(prior_anim, trial_num_in_block) %>%
  summarise(
    mean_deviation = mean(ppt_mean_deviation),
    ci_deviation = vector_confint(ppt_mean_deviation),
    n = sum(n)
  )

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = trial_num_in_block, y = mean_deviation,
      colour = prior_anim, fill = prior_anim
    )
  ) +
  theme_classic() +
  # theme(legend.position = "none") +
  labs(
    x = "Trial Number in Block",
    y = "Throw Angle (°)"
  )

# add horizontal lines
p <- p +
  geom_hline(
    yintercept = c(0, -30), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(-15), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  )

# add data points
p <- p + geom_beeswarm(
  data = data_per_ppt,
  aes(
    y = ppt_mean_deviation,
    colour = prior_anim
  ),
  size = 1, dodge.width = 0.5
) + geom_ribbon(
  aes(
    ymin = mean_deviation - ci_deviation,
    ymax = mean_deviation + ci_deviation
  ),
  colour = NA, alpha = 0.3
) + geom_line()


# set colour palette
p <- p +
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list)

ggplotly(p)

4 Deprecated (Don’t Run)

4.1 Success manifolds

4.1.1 Without any tilts

```r
# ggplotly(plot_success_manifold_no_tilt())
plot_success_manifold_no_tilt()

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->


### With tilt present

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuZ2dwbG90bHkocGxvdF9zdWNjZXNzX21hbmlmb2xkX3RpbHQoKSlcbmBgYFxuYGBgIn0= -->

```r
```r
ggplotly(plot_success_manifold_tilt())

```

LS0tDQp0aXRsZTogIkJpbGxpYXJkcyBhbmQgVGlsdHMgQW5hbHlzaXMgTm90ZWJvb2siDQphdXRob3I6ICJTaGFuYWF0aGFuYW4gTW9kY2hhbGluZ2FtIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnJtKGxpc3QgPSBscygpKSAjIGNsZWFuIGVudmlyb25tZW50DQoNCnNvdXJjZSgiLi4vc3JjL2hlbHBlcl9mdW5jcy5SIikNCnNvdXJjZSgiLi4vc2NyaXB0cy9maWd1cmVfZnVuY3MuUiIpDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2diZWVzd2FybSkNCmxpYnJhcnkoZXopICMgZm9yIEFOT1ZBcw0KbGlicmFyeShlZmZlY3RzaXplKSAjIGZvciBldGEtc3F1YXJlZA0KbGlicmFyeShwbG90bHkpDQoNCm9wdGlvbnMoZHBseXIuc3VtbWFyaXNlLmluZm9ybSA9IEYpDQoNCiMgdmFycw0Kb21uaWJ1c19wYXRoIDwtICIuLi9kYXRhL3Byb2Nlc3NlZC9vbW5pYnVzL29tbmlidXNfcmF3LmNzdiINCg0KIyBjb252ZXJ0IHRoZSBhYm92ZSBpbnRvIGEgbGlzdA0KcGFsbGV0ZV9saXN0IDwtIGMoDQogICJyb3QzMF9jdWVkX3RpbHQiID0gIiNkNDAwMDAiLA0KICAicm90MzBfdW5jdWVkIiA9ICIjZjk5ODJjIiwNCiAgImFjY2VsX2N1ZWRfdGlsdCIgPSAiIzA3NTA5YiIsDQogICJhY2NlbF91bmN1ZWQiID0gIiM1ZmI2OTYiLA0KICAiY3VydmVkX2N1ZWRfdGlsdCIgPSAiIzJiNTc0NyIsDQogICJyb3QxNV9jdWVkX3RpbHQiID0gIiM3NzAyMDIiLA0KICAicm90MTVfdW5jdWVkIiA9ICIjYTc2MzE1IiwNCiAgIm5vbmUiID0gIiNmOTk4MmMiLA0KICAiaGFsZl9hbmltIiA9ICIjNWZiNjk2IiwNCiAgImZ1bGxfYW5pbSIgPSAiIzA3NTA5YiIsDQogICJ3YWl0IiA9ICIjYTc2MzE1Ig0KKQ0KDQpOVU1fRVhQUyA8LSA3DQpgYGANCg0KDQoNCiMjIExvYWQgYWxsIG9mIHRoZSB0aHJvdyBkYXRhDQoNCg0KDQpgYGB7cn0NCiMgbG9hZCBvbW5pYnVzIGRhdGFmcmFtZQ0Kb21uaWJ1c19kZiA8LSByZWFkX2RlbGltKCIuLi9kYXRhL3Byb2Nlc3NlZC9vbW5pYnVzL29tbmlidXNfcmF3LmNzdiIsDQogIGRlbGltID0gIiwiLA0KICBjb2xfdHlwZXMgPSBjb2xzKA0KICAgIC5kZWZhdWx0ID0gY29sX2RvdWJsZSgpLA0KICAgIHR5cGUgPSBjb2xfZmFjdG9yKCksDQogICAgcHBpZCA9IGNvbF9mYWN0b3IoKSwNCiAgICBleHBfbGFiZWwgPSBjb2xfZmFjdG9yKCksDQogICAgZXhwZXJpbWVudCA9IGNvbF9mYWN0b3IoKSwNCiAgICBoYW5kID0gY29sX2ZhY3RvcigpLA0KICAgIGNhbWVyYV90aWx0ID0gY29sX2ZhY3RvcigpLA0KICAgIHN1cmZhY2VfdGlsdCA9IGNvbF9mYWN0b3IoKSwNCiAgICB0YXJnZXQgPSBjb2xfZmFjdG9yKCksDQogICAgdGVzdF90eXBlID0gY29sX2ZhY3RvcigpLA0KICAgIHByaW9yX2FuaW0gPSBjb2xfZmFjdG9yKCksDQogICAgYmFzZWxpbmVfYmxvY2sgPSBjb2xfZmFjdG9yKCksDQogICAgdGFza190eXBlID0gY29sX2ZhY3RvcigpLA0KICAgIHN1cmZhY2UgPSBjb2xfZmFjdG9yKCksDQogICAgYW5pbV90eXBlID0gY29sX2ZhY3RvcigpDQogICkNCikgJT4lDQogIGZpbHRlcihibG9ja19udW0gPiA0KSAjIGZpbHRlciBvdXQgcHJhY3RpY2UgYmxvY2tzDQpgYGANCg0KIyBWaXN1YWxpemluZyBkYXRhICh1bml2YXJpYXRlKQ0KVmVjdG9ycyByZXByZXNlbnRpbmcgdGhlIHRocm93IHZlbG9jaXR5ICh0cmFjZSAwKSBhbmQgdGhlIHZlbG9jaXR5IGFwcGxpZWQgdG8gdGhlIGJhbGwgKHRyYWNlIDEpLiBUaGUgeSBkaW1lbnRpb24gb2YgdGhlIHRocm93IGlzIGVzc2VudGlhbGx5IGlnbm9yZWQgKGluIHJlYWxpdHkgdGhlcmUgaXMgYSBzbGlnaHQgdGlsdCBhZGRlZCB0byBhY2NvdW50IGZvciB0aGUgdGlsdCBvZiB0aGUgc3VyZmFjZSkuDQpgYGB7cn0NCnRlc3RfcHB0IDwtIDMNCg0KdGVzdF9kZiA8LSBvbW5pYnVzX2RmICU+JSBmaWx0ZXIocHBpZCA9PSB0ZXN0X3BwdCkNCg0KDQp0cmlhbCA8LSAyNTANCnRyaWFsX2RmIDwtIGZpbHRlcih0ZXN0X2RmLCB0cmlhbF9udW0gPT0gdHJpYWwpDQoNCnggPC0gdHJpYWxfZGYkZmxpY2tfdmVsb2NpdHlfeCANCnkgPC0gdHJpYWxfZGYkZmxpY2tfdmVsb2NpdHlfeQ0KeiA8LSB0cmlhbF9kZiRmbGlja192ZWxvY2l0eV96DQoNCngyIDwtIHRyaWFsX2RmJGZsaWNrX2RpcmVjdGlvbl94ICogLTENCnkyIDwtIHRyaWFsX2RmJGZsaWNrX2RpcmVjdGlvbl95ICogLTENCnoyIDwtIHRyaWFsX2RmJGZsaWNrX2RpcmVjdGlvbl96ICogLTENCg0KIyBwbG90IGJvdGgNCnAgPC0gcGxvdF9seSh4ID0gYygwLCB4KSwgeSA9IGMoMCwgeSksIHogPSBjKDAsIHopLCB0eXBlID0gInNjYXR0ZXIzZCIsIG1vZGUgPSAibGluZXMiKSAlPiUNCiAgYWRkX3RyYWNlKHggPSBjKDAsIHgyKSwgeSA9IGMoMCwgeTIpLCB6ID0gYygwLCB6MiksIHR5cGUgPSAic2NhdHRlcjNkIiwgbW9kZSA9ICJsaW5lcyIpICU+JQ0KICBsYXlvdXQoc2NlbmUgPSBsaXN0KA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJ4IiwgcmFuZ2UgPSBjKC0yLCAyKSksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gInkiLCByYW5nZSA9IGMoLTEsIDMpKSwNCiAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAieiIsIHJhbmdlID0gYygtMSwgMykpDQogICkpDQoNCiMgUmVuZGVyIHRoZSBwbG90DQpwDQpgYGANCm5vdGU6IHRoaXMgaXMgYSByb3RhdGVkIHRyaWFsDQoNCiMjIyBEaXN0cmlidXRpb24gb2YgZXJyb3JzDQpgYGB7cn0NCiMgcGxvdCBkaXN0cmlidXRpb24gb2YgZXJyb3Jfc2l6ZQ0KcCA8LSBnZ3Bsb3Qob21uaWJ1c19kZiwgYWVzKHggPSBlcnJvcl9zaXplLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSB0eXBlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IC41LCBhbHBoYSA9IC42KSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI2Y5OTgyYyIsICIjZDQwMDAwIikpICsNCiAgbGFicyh4ID0gIkVycm9yIFNpemUgKGNtKSIsIHkgPSAiQ291bnQiKQ0KDQpwDQpgYGANCg0KIyMjIERpc3RyaWJ1dGlvbiBvZiB0aHJvdyBhbmdsZXMNCmBgYHtyfQ0KIyBwbG90IGRpc3RyaWJ1dGlvbiBvZiBlcnJvcl9zaXplDQpwIDwtIGdncGxvdChvbW5pYnVzX2RmLCBhZXMoeCA9IHRocm93X2RldmlhdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gdHlwZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBhbHBoYSA9IC42KSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI2Y5OTgyYyIsICIjZDQwMDAwIikpICsNCiAgbGFicygNCiAgICB4ID0gIlRocm93IEFuZ2xlICjCsCkiLCB5ID0gIkNvdW50Ig0KICApICsgICMgZGFzaGVkIGxpbmVzIGF0IDAsIC0xNSwgLTMwDQogIGdlb21fdmxpbmUoDQogICAgeGludGVyY2VwdCA9IGMoMCwgLTE1LCAtMzApLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJkYXNoZWQiDQogICkgKyAjIHRpY2tzIG9mIDE1IGRlZ3JlZXMNCiAgc2NhbGVfeF9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IGMoLTMwLCAwLCAzMCwgLTYwLCAtOTApDQogICkNCg0KcA0KYGBgDQoNCiMgT3JpZ2luYWwgRXhwZXJpbWVudHMNCg0KIyMjIFBsb3QgQU5HVUxBUiBERVZJQVRJT05TIChoYW5kIGFuZ2xlcykNCk5vdGU6IEJsdWVzID0gQWNjZWxlcmF0aW9uIFBlcnR1cmJhdGlvbnMNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCiMgcmVzdCBvZiB0aGUgZXhwcw0KZGF0YV9wZXJfZ3JvdXAgPC0gb21uaWJ1c19kZiAlPiUNCiAgZmlsdGVyKGV4cF9sYWJlbCA9PSAib3JpZ2luYWxfZXhwcyIgfCBleHBfbGFiZWwgPT0gImN1cnZlZF9wYXRoIikgJT4lDQogIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHRlc3RfdHlwZSwgdHJpYWxfbnVtKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW5fZGV2aWF0aW9uID0gbWVhbih0aHJvd19kZXZpYXRpb24pLA0KICAgIGNpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KHRocm93X2RldmlhdGlvbiksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApDQoNCiMgc2V0IHVwIHBsb3QNCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4ID0gdHJpYWxfbnVtLCB5ID0gbWVhbl9kZXZpYXRpb24sIGNvbG91ciA9IGV4cGVyaW1lbnQNCiAgICApDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICAjIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKA0KICAgIHggPSAiVHJpYWwgTnVtYmVyIiwNCiAgICB5ID0gIlRocm93IEFuZ2xlICjCsCkiDQogICkNCg0KIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KcCA8LSBwICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLCAtMzApLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoLTE1KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApDQoNCiMgcCA8LSBwICsNCiMgICBzY2FsZV95X2NvbnRpbnVvdXMoDQojICAgICBsaW1pdHMgPSBjKC0xMCwgMzUpLA0KIyAgICAgYnJlYWtzID0gYygwLCAxNSwgMzApLA0KIyAgICAgbGFiZWxzID0gYygwLCAxNSwgMzApDQojICAgKSArDQojICAgc2NhbGVfeF9jb250aW51b3VzKA0KIyAgICAgbGltaXRzID0gYygwLCAxODApLA0KIyAgICAgYnJlYWtzID0gYygwLCA2MCwgMTIwLCAxODApLA0KIyAgICAgbGFiZWxzID0gYygwLCA2MCwgMTIwLCAxODApDQojICAgKQ0KDQojIHNldCBmb250IHNpemUgdG8gMTENCnAgPC0gcCArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSkNCg0KIyBhZGQgY29uZmlkZW5jZSBpbnRlcnZhbHMgYW5kIGRhdGEgcG9pbnRzDQpwIDwtIHAgKyBnZW9tX3JpYmJvbigNCiAgYWVzKA0KICAgIHltaW4gPSBtZWFuX2RldmlhdGlvbiAtIGNpX2RldmlhdGlvbiwNCiAgICB5bWF4ID0gbWVhbl9kZXZpYXRpb24gKyBjaV9kZXZpYXRpb24sDQogICAgZmlsbCA9IGV4cGVyaW1lbnQNCiAgKSwNCiAgY29sb3VyID0gTkEsIGFscGhhID0gMC4zDQopICsgZ2VvbV9saW5lKCkNCg0KIyBzZXQgY29sb3VyIHBhbGV0dGUNCnAgPC0gcCArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkNCg0KDQojICMgc2F2ZQ0KIyBpZiAoc2F2ZV9wbG90cykgew0KIyAgIGdnc2F2ZSgNCiMgICBwLA0KIyAgIGZpbGVuYW1lID0gIi4uL3Bsb3RzL3BhcGVyX2ZpZ3Mvc3JfMzBfdHJhaW5pbmcucGRmIiwgZGV2aWNlID0gInBkZiIsDQojICAgaGVpZ2h0ID0gNCwgd2lkdGggPSA2DQojICAgKQ0KIyAgIH0NCg0KZ2dwbG90bHkocCkNCg0KIyBwDQpgYGANCiMjIyBUcmlhbCBzZXRzIG9mIGludGVyZXN0IG9ubHkNCk5vdGU6IEJsdWVzID0gQWNjZWxlcmF0aW9uIFBlcnR1cmJhdGlvbnMNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCiMgZmlsdGVyIG91dCBqdXN0IHRoZSB0cmlhbHMgb2YgaW50ZXJlc3QNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBmaWx0ZXIoDQogICAgdGVzdF90eXBlICE9ICJvdGhlciINCiAgKQ0KIyBhZGQgYSBkdW1teSBjb2x1bW4gd2l0aCByZXBlYXRpbmcgc2VxdWVuY2UNCiMgTk9URTogdGhpcyBjYW4ndCBiZSBjb21iaW5lZCB3aXRoIGFib3ZlIHNpbmNlIHdlIGFyZSB1c2luZyBucm93DQpkYXRhX3Blcl9ncm91cCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgbXV0YXRlKGR1bW15X3ggPSByZXAoMToobnJvdyhkYXRhX3Blcl9ncm91cCkgLyBOVU1fRVhQUyksDQogICAgbGVuZ3RoLm91dCA9IG5yb3coZGF0YV9wZXJfZ3JvdXApDQogICkpDQoNCiMgc2V0IHVwIHBsb3QNCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4ID0gZHVtbXlfeCwgeSA9IG1lYW5fZGV2aWF0aW9uLCBjb2xvdXIgPSBleHBlcmltZW50DQogICAgKQ0KICApICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgIyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgbGFicygNCiAgICB4ID0gIlRyaWFsIE51bWJlciIsDQogICAgeSA9ICJUaHJvdyBBbmdsZSAowrApIg0KICApDQoNCiMgYWRkIGhvcml6b250YWwgbGluZXMNCnAgPC0gcCArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMCwgLTMwKSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAic29saWQiDQogICkgKw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKC0xNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKQ0KDQojIGFkZCBjb25maWRlbmNlIGludGVydmFscyBhbmQgZGF0YSBwb2ludHMNCmZvciAodW5pcXVlX3Rlc3RfdHlwZSBpbiB1bmlxdWUoZGF0YV9wZXJfZ3JvdXAkdGVzdF90eXBlKSkgew0KICAjIGdldCB0aGUgZGF0YSBmb3IgdGhpcyBibG9jaw0KICB0b19wbG90X2RhdGEgPC0gZmlsdGVyKGRhdGFfcGVyX2dyb3VwLCB0ZXN0X3R5cGUgPT0gdW5pcXVlX3Rlc3RfdHlwZSkNCg0KICBwIDwtIHAgKyBnZW9tX3JpYmJvbigNCiAgICBkYXRhID0gdG9fcGxvdF9kYXRhLA0KICAgIGFlcygNCiAgICAgIHltaW4gPSBtZWFuX2RldmlhdGlvbiAtIGNpX2RldmlhdGlvbiwNCiAgICAgIHltYXggPSBtZWFuX2RldmlhdGlvbiArIGNpX2RldmlhdGlvbiwNCiAgICAgIGZpbGwgPSBleHBlcmltZW50DQogICAgKSwgY29sb3VyID0gTkEsIGFscGhhID0gMC4zDQogICkgKyBnZW9tX2xpbmUoDQogICAgZGF0YSA9IHRvX3Bsb3RfZGF0YQ0KICApDQp9DQoNCiMgc2V0IGNvbG91ciBwYWxldHRlDQpwIDwtIHAgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpDQoNCmdncGxvdGx5KHApDQpgYGANCiMjIyBQbG90IE5PUk1BTElaRUQgQU5HVUxBUiBERVZJQVRJT05TIChoYW5kIGFuZ2xlcykNCk5vdGU6IEJsdWVzID0gQWNjZWxlcmF0aW9uIFBlcnR1cmJhdGlvbnMNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCiMgcmVzdCBvZiB0aGUgZXhwcw0KZGF0YV9wZXJfZ3JvdXAgPC0gb21uaWJ1c19kZiAlPiUNCiAgZmlsdGVyKGV4cF9sYWJlbCA9PSAib3JpZ2luYWxfZXhwcyIgfCBleHBfbGFiZWwgPT0gImN1cnZlZF9wYXRoIikgJT4lDQogIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHRlc3RfdHlwZSwgdHJpYWxfbnVtKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW5fZGV2aWF0aW9uID0gbWVhbihub3JtX3Rocm93X2RldmlhdGlvbiksDQogICAgY2lfZGV2aWF0aW9uID0gdmVjdG9yX2NvbmZpbnQobm9ybV90aHJvd19kZXZpYXRpb24pLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQojIHNldCB1cCBwbG90DQpwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKA0KICAgICAgeCA9IHRyaWFsX251bSwgeSA9IG1lYW5fZGV2aWF0aW9uLCBjb2xvdXIgPSBleHBlcmltZW50DQogICAgKQ0KICApICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgIyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgbGFicygNCiAgICB4ID0gIlRyaWFsIE51bWJlciIsDQogICAgeSA9ICJOb3JtYWxpemVkIFRocm93IEFuZ2xlIg0KICApDQoNCiMgYWRkIGhvcml6b250YWwgbGluZXMNCnAgPC0gcCArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMCwgMSwgMiksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLjUsIDEuNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKQ0KDQojIHAgPC0gcCArDQojICAgc2NhbGVfeV9jb250aW51b3VzKA0KIyAgICAgbGltaXRzID0gYygtMTAsIDM1KSwNCiMgICAgIGJyZWFrcyA9IGMoMCwgMTUsIDMwKSwNCiMgICAgIGxhYmVscyA9IGMoMCwgMTUsIDMwKQ0KIyAgICkgKw0KIyAgIHNjYWxlX3hfY29udGludW91cygNCiMgICAgIGxpbWl0cyA9IGMoMCwgMTgwKSwNCiMgICAgIGJyZWFrcyA9IGMoMCwgNjAsIDEyMCwgMTgwKSwNCiMgICAgIGxhYmVscyA9IGMoMCwgNjAsIDEyMCwgMTgwKQ0KIyAgICkNCg0KIyBzZXQgZm9udCBzaXplIHRvIDExDQpwIDwtIHAgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkpDQoNCiMgYWRkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFuZCBkYXRhIHBvaW50cw0KcCA8LSBwICsgZ2VvbV9yaWJib24oDQogIGFlcygNCiAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgeW1heCA9IG1lYW5fZGV2aWF0aW9uICsgY2lfZGV2aWF0aW9uLA0KICAgIGZpbGwgPSBleHBlcmltZW50DQogICksDQogIGNvbG91ciA9IE5BLCBhbHBoYSA9IDAuMw0KKSArIGdlb21fbGluZSgpDQoNCiMgc2V0IGNvbG91ciBwYWxldHRlDQpwIDwtIHAgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpDQoNCg0KIyAjIHNhdmUNCiMgaWYgKHNhdmVfcGxvdHMpIHsNCiMgICBnZ3NhdmUoDQojICAgcCwNCiMgICBmaWxlbmFtZSA9ICIuLi9wbG90cy9wYXBlcl9maWdzL3NyXzMwX3RyYWluaW5nLnBkZiIsIGRldmljZSA9ICJwZGYiLA0KIyAgIGhlaWdodCA9IDQsIHdpZHRoID0gNg0KIyAgICkNCiMgICB9DQoNCmdncGxvdGx5KHApDQoNCiMgcA0KYGBgDQojIyMgVHJpYWwgc2V0cyBvZiBpbnRlcmVzdCBvbmx5DQpOb3RlOiBCbHVlcyA9IEFjY2VsZXJhdGlvbiBQZXJ0dXJiYXRpb25zDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQojIGZpbHRlciBvdXQganVzdCB0aGUgdHJpYWxzIG9mIGludGVyZXN0DQpkYXRhX3Blcl9ncm91cCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZmlsdGVyKA0KICAgIHRlc3RfdHlwZSAhPSAib3RoZXIiDQogICkNCiMgYWRkIGEgZHVtbXkgY29sdW1uIHdpdGggcmVwZWF0aW5nIHNlcXVlbmNlDQojIE5PVEU6IHRoaXMgY2FuJ3QgYmUgY29tYmluZWQgd2l0aCBhYm92ZSBzaW5jZSB3ZSBhcmUgdXNpbmcgbnJvdw0KZGF0YV9wZXJfZ3JvdXAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIG11dGF0ZShkdW1teV94ID0gcmVwKDE6KG5yb3coZGF0YV9wZXJfZ3JvdXApIC8gTlVNX0VYUFMpLA0KICAgIGxlbmd0aC5vdXQgPSBucm93KGRhdGFfcGVyX2dyb3VwKQ0KICApKQ0KDQojIHNldCB1cCBwbG90DQpwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKA0KICAgICAgeCA9IGR1bW15X3gsIHkgPSBtZWFuX2RldmlhdGlvbiwgY29sb3VyID0gZXhwZXJpbWVudA0KICAgICkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGxhYnMoDQogICAgeCA9ICJUcmlhbCBOdW1iZXIiLA0KICAgIHkgPSAiTm9ybWFsaXplZCBUaHJvdyBBbmdsZSINCiAgKQ0KDQojIGFkZCBob3Jpem9udGFsIGxpbmVzDQpwIDwtIHAgKw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIDEsIDIpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMC41LCAxLjUpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJkYXNoZWQiDQogICkNCg0KIyBhZGQgY29uZmlkZW5jZSBpbnRlcnZhbHMgYW5kIGRhdGEgcG9pbnRzDQpmb3IgKHVuaXF1ZV90ZXN0X3R5cGUgaW4gdW5pcXVlKGRhdGFfcGVyX2dyb3VwJHRlc3RfdHlwZSkpIHsNCiAgIyBnZXQgdGhlIGRhdGEgZm9yIHRoaXMgYmxvY2sNCiAgdG9fcGxvdF9kYXRhIDwtIGZpbHRlcihkYXRhX3Blcl9ncm91cCwgdGVzdF90eXBlID09IHVuaXF1ZV90ZXN0X3R5cGUpDQoNCiAgcCA8LSBwICsgZ2VvbV9yaWJib24oDQogICAgZGF0YSA9IHRvX3Bsb3RfZGF0YSwNCiAgICBhZXMoDQogICAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgICB5bWF4ID0gbWVhbl9kZXZpYXRpb24gKyBjaV9kZXZpYXRpb24sDQogICAgICBmaWxsID0gZXhwZXJpbWVudA0KICAgICksIGNvbG91ciA9IE5BLCBhbHBoYSA9IDAuMw0KICApICsgZ2VvbV9saW5lKA0KICAgIGRhdGEgPSB0b19wbG90X2RhdGENCiAgKQ0KfQ0KDQojIHNldCBjb2xvdXIgcGFsZXR0ZQ0KcCA8LSBwICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KQ0KDQpnZ3Bsb3RseShwKQ0KYGBgDQoNCiMjIyBQbG90IEVSUk9SIFNJWkUNCk5vdGU6IEJsdWVzID0gQWNjZWxlcmF0aW9uIFBlcnR1cmJhdGlvbnMNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCiMgb3JpZ2luYWwgZXhwZXJpbWVudHMgb25seQ0KZGF0YV9wZXJfZ3JvdXAgPC0gb21uaWJ1c19kZiAlPiUNCiAgZmlsdGVyKGV4cF9sYWJlbCA9PSAib3JpZ2luYWxfZXhwcyIgfCBleHBfbGFiZWwgPT0gImN1cnZlZF9wYXRoIikgJT4lDQogIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHRlc3RfdHlwZSwgdHJpYWxfbnVtKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW5fZGV2aWF0aW9uID0gbWVhbihlcnJvcl9zaXplKSwNCiAgICBjaV9kZXZpYXRpb24gPSB2ZWN0b3JfY29uZmludChlcnJvcl9zaXplKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkNCg0KIyBzZXQgdXAgcGxvdA0KcCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcygNCiAgICAgIHggPSB0cmlhbF9udW0sIHkgPSBtZWFuX2RldmlhdGlvbiwgY29sb3VyID0gZXhwZXJpbWVudA0KICAgICkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGxhYnMoDQogICAgeCA9ICJUcmlhbCBOdW1iZXIiLA0KICAgIHkgPSAiQWJzb2x1dGUgVGFyZ2V0IEVycm9yIChjbSkiDQogICkNCg0KIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KcCA8LSBwICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLCA0MCksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygyMCksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKQ0KDQojIHAgPC0gcCArDQojICAgc2NhbGVfeV9jb250aW51b3VzKA0KIyAgICAgbGltaXRzID0gYygtMTAsIDM1KSwNCiMgICAgIGJyZWFrcyA9IGMoMCwgMTUsIDMwKSwNCiMgICAgIGxhYmVscyA9IGMoMCwgMTUsIDMwKQ0KIyAgICkgKw0KIyAgIHNjYWxlX3hfY29udGludW91cygNCiMgICAgIGxpbWl0cyA9IGMoMCwgMTgwKSwNCiMgICAgIGJyZWFrcyA9IGMoMCwgNjAsIDEyMCwgMTgwKSwNCiMgICAgIGxhYmVscyA9IGMoMCwgNjAsIDEyMCwgMTgwKQ0KIyAgICkNCg0KIyBzZXQgZm9udCBzaXplIHRvIDExDQpwIDwtIHAgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkpDQoNCiMgYWRkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFuZCBkYXRhIHBvaW50cw0KcCA8LSBwICsgZ2VvbV9yaWJib24oDQogIGFlcygNCiAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgeW1heCA9IG1lYW5fZGV2aWF0aW9uICsgY2lfZGV2aWF0aW9uLA0KICAgIGZpbGwgPSBleHBlcmltZW50DQogICksDQogIGNvbG91ciA9IE5BLCBhbHBoYSA9IDAuMw0KKSArIGdlb21fbGluZSgpDQoNCiMgc2V0IGNvbG91ciBwYWxldHRlDQpwIDwtIHAgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpDQoNCg0KIyAjIHNhdmUNCiMgaWYgKHNhdmVfcGxvdHMpIHsNCiMgICBnZ3NhdmUoDQojICAgcCwNCiMgICBmaWxlbmFtZSA9ICIuLi9wbG90cy9wYXBlcl9maWdzL3NyXzMwX3RyYWluaW5nLnBkZiIsIGRldmljZSA9ICJwZGYiLA0KIyAgIGhlaWdodCA9IDQsIHdpZHRoID0gNg0KIyAgICkNCiMgICB9DQoNCmdncGxvdGx5KHApDQoNCiMgcA0KYGBgDQoNCnZpc2libGUgdnMgbm9uLXZpc2libGUgdGlsdCBkb2Vzbid0IGFmZmVjdCB0aGUgMTUtZGVncmVlIHJvdGF0aW9uIGNvbmRpdGlvbi4gQnV0IGFmZmVjdHMgYWxsIG90aGVyIGNvbmRpdGlvbnMuIFNvIDE1LWRlZ3JlZSByb3RhdGlvbg0KDQojIyMgVHJpYWwgc2V0cyBvZiBpbnRlcmVzdCBvbmx5DQpOb3RlOiBCbHVlcyA9IEFjY2VsZXJhdGlvbiBQZXJ0dXJiYXRpb25zDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQojIGZpbHRlciBvdXQganVzdCB0aGUgdHJpYWxzIG9mIGludGVyZXN0DQpkYXRhX3Blcl9ncm91cCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZmlsdGVyKA0KICAgIHRlc3RfdHlwZSAhPSAib3RoZXIiDQogICkNCiMgYWRkIGEgZHVtbXkgY29sdW1uIHdpdGggcmVwZWF0aW5nIHNlcXVlbmNlDQojIE5PVEU6IHRoaXMgY2FuJ3QgYmUgY29tYmluZWQgd2l0aCBhYm92ZSBzaW5jZSB3ZSBhcmUgdXNpbmcgbnJvdw0KZGF0YV9wZXJfZ3JvdXAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIG11dGF0ZShkdW1teV94ID0gcmVwKDE6KG5yb3coZGF0YV9wZXJfZ3JvdXApIC8gTlVNX0VYUFMpLA0KICAgIGxlbmd0aC5vdXQgPSBucm93KGRhdGFfcGVyX2dyb3VwKQ0KICApKQ0KDQojIHNldCB1cCBwbG90DQpwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKA0KICAgICAgeCA9IGR1bW15X3gsIHkgPSBtZWFuX2RldmlhdGlvbiwgY29sb3VyID0gZXhwZXJpbWVudA0KICAgICkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGxhYnMoDQogICAgeCA9ICJUcmlhbCBOdW1iZXIiLA0KICAgIHkgPSAiQWJzb2x1dGUgVGFyZ2V0IEVycm9yIChjbSkiDQogICkNCg0KIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KcCA8LSBwICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLCA0MCksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygyMCksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKQ0KDQojIGFkZCBjb25maWRlbmNlIGludGVydmFscyBhbmQgZGF0YSBwb2ludHMNCmZvciAodW5pcXVlX3Rlc3RfdHlwZSBpbiB1bmlxdWUoZGF0YV9wZXJfZ3JvdXAkdGVzdF90eXBlKSkgew0KICAjIGdldCB0aGUgZGF0YSBmb3IgdGhpcyBibG9jaw0KICB0b19wbG90X2RhdGEgPC0gZmlsdGVyKGRhdGFfcGVyX2dyb3VwLCB0ZXN0X3R5cGUgPT0gdW5pcXVlX3Rlc3RfdHlwZSkNCg0KICBwIDwtIHAgKyBnZW9tX3JpYmJvbigNCiAgICBkYXRhID0gdG9fcGxvdF9kYXRhLA0KICAgIGFlcygNCiAgICAgIHltaW4gPSBtZWFuX2RldmlhdGlvbiAtIGNpX2RldmlhdGlvbiwNCiAgICAgIHltYXggPSBtZWFuX2RldmlhdGlvbiArIGNpX2RldmlhdGlvbiwNCiAgICAgIGZpbGwgPSBleHBlcmltZW50DQogICAgKSwgY29sb3VyID0gTkEsIGFscGhhID0gMC4zDQogICkgKyBnZW9tX2xpbmUoDQogICAgZGF0YSA9IHRvX3Bsb3RfZGF0YQ0KICApDQp9DQoNCiMgc2V0IGNvbG91ciBwYWxldHRlDQpwIDwtIHAgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpDQoNCmdncGxvdGx5KHApDQpgYGANCg0KDQoNCiMgQW5pbWF0ZWQgU3VyZmFjZSBGb2xsb3ctdXANCg0KIyMjIFBsb3QgQU5HVUxBUiBERVZJQVRJT05TIChoYW5kIGFuZ2xlcykNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCiMgaXNvbGF0ZSBhbmltYXRlX3N1cmZhY2UgZXhwDQpkYXRhX3Blcl9ncm91cCA8LSBvbW5pYnVzX2RmICU+JQ0KICBmaWx0ZXIoZXhwX2xhYmVsID09ICJhbmltYXRlX3N1cmZhY2UiKSAlPiUNCiAgZ3JvdXBfYnkocHJpb3JfYW5pbSwgYmxvY2tfbnVtLCB0cmlhbF9udW1faW5fYmxvY2ssIHRyaWFsX251bSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuX2RldmlhdGlvbiA9IG1lYW4odGhyb3dfZGV2aWF0aW9uKSwNCiAgICBjaV9kZXZpYXRpb24gPSB2ZWN0b3JfY29uZmludCh0aHJvd19kZXZpYXRpb24pDQogICkNCg0KIyBvcmRlciB0aGUgZmFjdG9ycyBmb3IgYXNzaWduaW5nIGNvbG91ciBwYWxsZXRzDQpkYXRhX3Blcl9ncm91cCRwcmlvcl9hbmltIDwtIGZhY3RvcigNCiAgZGF0YV9wZXJfZ3JvdXAkcHJpb3JfYW5pbSwNCiAgbGV2ZWxzID0gYygNCiAgICAibm9uZSIsICJoYWxmX2FuaW0iLCAiZnVsbF9hbmltIg0KICApDQopDQoNCiMgc2V0IHVwIHBsb3QNCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4ID0gdHJpYWxfbnVtLCB5ID0gbWVhbl9kZXZpYXRpb24sDQogICAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgICB5bWF4ID0gbWVhbl9kZXZpYXRpb24gKyBjaV9kZXZpYXRpb24NCiAgICApDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICAjIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKA0KICAgIHggPSAiVHJpYWwgTnVtYmVyIiwNCiAgICB5ID0gIlRocm93IEFuZ2xlICjCsCkiDQogICkNCg0KIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KcCA8LSBwICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLCAtMzApLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoLTE1KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApDQoNCiMgcCA8LSBwICsNCiMgICBzY2FsZV95X2NvbnRpbnVvdXMoDQojICAgICBsaW1pdHMgPSBjKC0xMCwgMzUpLA0KIyAgICAgYnJlYWtzID0gYygwLCAxNSwgMzApLA0KIyAgICAgbGFiZWxzID0gYygwLCAxNSwgMzApDQojICAgKSArDQojICAgc2NhbGVfeF9jb250aW51b3VzKA0KIyAgICAgbGltaXRzID0gYygwLCAxODApLA0KIyAgICAgYnJlYWtzID0gYygwLCA2MCwgMTIwLCAxODApLA0KIyAgICAgbGFiZWxzID0gYygwLCA2MCwgMTIwLCAxODApDQojICAgKQ0KDQojIHNldCBmb250IHNpemUgdG8gMTENCnAgPC0gcCArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSkNCg0KIyByZXBlYXQgZm9yIHByaW9yX2FuaW0gPT0gImhhbGYiLCAiZnVsbCIgYW5kICJ3YWl0Ig0KZm9yICh1bmlxdWVfcHJpb3JfYW5pbSBpbiB1bmlxdWUoZGF0YV9wZXJfZ3JvdXAkcHJpb3JfYW5pbSkpIHsNCiAgIyBnZXQgdGhlIGRhdGEgZm9yIHRoaXMgYmxvY2sNCiAgdG9fcGxvdF9kYXRhIDwtIGZpbHRlcihkYXRhX3Blcl9ncm91cCwgcHJpb3JfYW5pbSA9PSB1bmlxdWVfcHJpb3JfYW5pbSkNCiAgIyBsb29wIHRocm91Z2ggdGhlIHVuaXF1ZSBibG9ja3MgaW4gdG9fcGxvdF9kYXRhDQogIGZvciAoYmxvY2sgaW4gdW5pcXVlKHRvX3Bsb3RfZGF0YSRibG9ja19udW0pKSB7DQogICAgIyBnZXQgdGhlIGRhdGEgZm9yIHRoaXMgYmxvY2sNCiAgICBibG9ja19kYXRhIDwtIGZpbHRlcih0b19wbG90X2RhdGEsIGJsb2NrX251bSA9PSBibG9jaykNCiAgICAjIGFkZCB0aGUgZGF0YSwgdXNlIHRoZSBwYWxsZXRlX2xpc3QgdG8gZ2V0IHRoZSBjb2xvdXINCiAgICBwIDwtIHAgKyBnZW9tX3JpYmJvbigNCiAgICAgIGRhdGEgPSBibG9ja19kYXRhLA0KICAgICAgYWVzKGZpbGwgPSBwcmlvcl9hbmltKSwNCiAgICAgIGNvbG91ciA9IE5BLCBhbHBoYSA9IDAuMw0KICAgICkgKyBnZW9tX2xpbmUoDQogICAgICBkYXRhID0gYmxvY2tfZGF0YSwNCiAgICAgIGFlcyhjb2xvdXIgPSBwcmlvcl9hbmltKQ0KICAgICkNCiAgfQ0KfQ0KDQojIHNldCBjb2xvdXIgcGFsZXR0ZQ0KcCA8LSBwICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KQ0KDQojICMgc2F2ZQ0KIyBpZiAoc2F2ZV9wbG90cykgew0KIyAgIGdnc2F2ZSgNCiMgICBwLA0KIyAgIGZpbGVuYW1lID0gIi4uL3Bsb3RzL3BhcGVyX2ZpZ3Mvc3JfMzBfdHJhaW5pbmcucGRmIiwgZGV2aWNlID0gInBkZiIsDQojICAgaGVpZ2h0ID0gNCwgd2lkdGggPSA2DQojICAgKQ0KIyAgIH0NCg0KZ2dwbG90bHkocCkNCiMgcA0KYGBgDQoNCiMjIyBXYXNob3V0IHRyaWFscyBhZnRlciBoYWxmIFZTIGZ1bGwgYW5pbWF0aW9ucw0KYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02LCBvdXQud2lkdGg9IjEwMCUifQ0KIyBmaXJzdCwgaXNvbGF0ZSB0aGUgZGF0YQ0KZGF0YSA8LSBvbW5pYnVzX2RmICU+JQ0KICBmaWx0ZXIoDQogICAgZXhwX2xhYmVsID09ICJhbmltYXRlX3N1cmZhY2UiLA0KICAgIGJhc2VsaW5lX2Jsb2NrID09IEZBTFNFLA0KICAgIHRlc3RfdHlwZSA9PSAid2FzaG91dF9hbmltIg0KICApDQoNCmRhdGFfcGVyX3BwdCA8LSBkYXRhICU+JQ0KICBncm91cF9ieShwcGlkLCBwcmlvcl9hbmltLCB0cmlhbF9udW1faW5fYmxvY2spICU+JQ0KICBzdW1tYXJpc2UoDQogICAgcHB0X21lYW5fZGV2aWF0aW9uID0gbWVkaWFuKHRocm93X2RldmlhdGlvbiksDQogICAgcHB0X2NpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KHRocm93X2RldmlhdGlvbiksDQogICAgbiA9IG4oKQ0KICApDQoNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX3BwdCAlPiUNCiAgZ3JvdXBfYnkocHJpb3JfYW5pbSwgdHJpYWxfbnVtX2luX2Jsb2NrKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW5fZGV2aWF0aW9uID0gbWVhbihwcHRfbWVhbl9kZXZpYXRpb24pLA0KICAgIGNpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KHBwdF9tZWFuX2RldmlhdGlvbiksDQogICAgbiA9IHN1bShuKQ0KICApDQoNCiMgc2V0IHVwIHBsb3QNCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4ID0gdHJpYWxfbnVtX2luX2Jsb2NrLCB5ID0gbWVhbl9kZXZpYXRpb24sDQogICAgICBjb2xvdXIgPSBwcmlvcl9hbmltLCBmaWxsID0gcHJpb3JfYW5pbQ0KICAgICkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGxhYnMoDQogICAgeCA9ICJUcmlhbCBOdW1iZXIgaW4gQmxvY2siLA0KICAgIHkgPSAiVGhyb3cgQW5nbGUgKMKwKSINCiAgKQ0KDQojIGFkZCBob3Jpem9udGFsIGxpbmVzDQpwIDwtIHAgKw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIC0zMCksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygtMTUpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJkYXNoZWQiDQogICkNCg0KIyBhZGQgZGF0YSBwb2ludHMNCnAgPC0gcCArIGdlb21fYmVlc3dhcm0oDQogIGRhdGEgPSBkYXRhX3Blcl9wcHQsDQogIGFlcygNCiAgICB5ID0gcHB0X21lYW5fZGV2aWF0aW9uLA0KICAgIGNvbG91ciA9IHByaW9yX2FuaW0NCiAgKSwNCiAgc2l6ZSA9IDEsIGRvZGdlLndpZHRoID0gMC41DQopICsgZ2VvbV9yaWJib24oDQogIGFlcygNCiAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgeW1heCA9IG1lYW5fZGV2aWF0aW9uICsgY2lfZGV2aWF0aW9uDQogICksDQogIGNvbG91ciA9IE5BLCBhbHBoYSA9IDAuMw0KKSArIGdlb21fbGluZSgpDQoNCg0KIyBzZXQgY29sb3VyIHBhbGV0dGUNCnAgPC0gcCArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkNCg0KZ2dwbG90bHkocCkNCmBgYA0KDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KIyMgRU1QVFkNCmBgYA0KDQoNCiMgRGVwcmVjYXRlZCAoRG9uJ3QgUnVuKQ0KDQojIyBTdWNjZXNzIG1hbmlmb2xkcw0KIyMjIFdpdGhvdXQgYW55IHRpbHRzDQpgYGB7ciwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9MjB9DQojIGdncGxvdGx5KHBsb3Rfc3VjY2Vzc19tYW5pZm9sZF9ub190aWx0KCkpDQpwbG90X3N1Y2Nlc3NfbWFuaWZvbGRfbm9fdGlsdCgpDQpgYGANCg0KIyMjIFdpdGggdGlsdCBwcmVzZW50DQpgYGB7ciwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9MjB9DQpnZ3Bsb3RseShwbG90X3N1Y2Nlc3NfbWFuaWZvbGRfdGlsdCgpKQ0KYGBgDQoNCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpOVUxMDQpgYGANCg0K